package xyz.ibenben.zhongdian.system.service.impl;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xyz.ibenben.zhongdian.common.annotation.SystemServiceLog;
import xyz.ibenben.zhongdian.common.constants.Constants;
import xyz.ibenben.zhongdian.system.dao.InnerMailDao;
import xyz.ibenben.zhongdian.system.entity.InnerMail;
import xyz.ibenben.zhongdian.system.entity.InnerMailRecord;
import xyz.ibenben.zhongdian.system.entity.sys.SysUser;
import xyz.ibenben.zhongdian.system.form.InnerMailForm;
import xyz.ibenben.zhongdian.system.mapper.InnerMailMapper;
import xyz.ibenben.zhongdian.system.service.InnerMailRecordService;
import xyz.ibenben.zhongdian.system.service.InnerMailService;
import xyz.ibenben.zhongdian.system.service.sys.SysUserService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 站内信服务实现类
 * 提供了一些基本的服务，如获取公告、查询个人消息、查询每条消息的详细信息等方法
 * 主要用于用户之间通信使用此类来维护
 *
 * @author chenjian
 * @since 2017年9月27日上午10:57:28
 */
@Service("innerMailService")
public class InnerMailServiceImpl extends AbstractServiceImpl<InnerMail> implements InnerMailService {
    @Resource
    private InnerMailDao innerMailDao;
    @Resource
    private InnerMailMapper innerMailMapper;
    @Resource
    private InnerMailRecordService innerMailRecordService;
    @Resource
    private SysUserService sysUserService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    @SystemServiceLog(description = "save站内信记录")
    public int save(InnerMail entity, HttpServletRequest request) {
        entity.setCreateId((Long) request.getSession().getAttribute(Constants.SESSIONID));
        entity.setCreateTime(new Date());
        entity.setUpdateId((Long) request.getSession().getAttribute(Constants.SESSIONID));
        entity.setUpdateTime(new Date());
        int result = innerMailDao.insert(entity);
        if (entity.getType().ordinal() == 0 || entity.getType().ordinal() == 1) {
            List<SysUser> userList = sysUserService.findByType(entity.getType().ordinal());
            for (SysUser user : userList) {
                this.buildEntity(entity.getId(), user.getId(), request);
            }
        } else {
            this.buildEntity(entity.getId(), entity.getToId(), request);
        }
        return result;
    }

    /**
     * 构建实体类
     *
     * @param id      参数
     * @param toId    参数
     * @param request 参数
     */
    private void buildEntity(Long id, Long toId, HttpServletRequest request) {
        InnerMailRecord imr = new InnerMailRecord();
        imr.setImId(id);
        imr.setToId(toId);
        imr.setIsRead(false);
        imr.setSendTime(new Date());
        innerMailRecordService.save(imr, request);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @SystemServiceLog(description = "delete站内信记录")
    public int delete(Object key, HttpServletRequest request) {
        int result = 0;
        int resultIMR = innerMailRecordService.deleteByInnerMailKey(key, request);
        InnerMail entity = this.selectByKey(key);
        entity.setDelFlag(0);
        entity.setDelId((Long) request.getSession().getAttribute(Constants.SESSIONID));
        entity.setDelTime(new Date());
        int resultIM = innerMailDao.updateByPrimaryKey(entity);
        if (resultIMR != 0 && resultIM != 0) {
            result = resultIM;
        }
        return result;
    }

    @Override
    @SystemServiceLog(description = "findAllNoticeByUserId站内信记录")
    public List<InnerMail> findAllNoticeByUserId(Long userId, Integer type) {
        Map<String, Object> map = new HashMap<>(3);
        map.put("userId", userId);
        map.put("type", type);
        return innerMailMapper.findAllNoticeByUserId(map);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    @SystemServiceLog(description = "selectByKeyAndUserId站内信记录")
    public InnerMail selectByKeyAndUserId(Long id, HttpServletRequest request) {
        Long userId = (Long) request.getSession().getAttribute(Constants.SESSIONID);
        InnerMail innerMail = this.selectByKey(id);
        innerMail.setFromUserName(sysUserService.selectByKey(innerMail.getFromId()).getUsername());
        SysUser user = sysUserService.selectByKey(userId);
        InnerMailRecord record = innerMailRecordService.selectByMailIdAndUserId(id, userId);
        innerMail.setIsRead(record.getIsRead());
        innerMail.setSendTime(record.getSendTime());
        innerMail.setToId(record.getToId());
        innerMail.setToUserName(user.getUsername());
        record.setIsRead(true);
        innerMailRecordService.updateAll(record, request);
        return innerMail;
    }

    @Override
    @SystemServiceLog(description = "selectByKeyWithList站内信记录")
    public InnerMail selectByKeyWithList(Long id) {
        Map<String, Object> map = new HashMap<>(1);
        map.put("key", id);
        return innerMailMapper.findByPrimaryKey(map);
    }

    @Override
    @SystemServiceLog(description = "getAllDetail站内信记录")
    public List<InnerMail> getAllDetail(String title, Boolean isRead, HttpServletRequest request) {
        Long userId = (Long) request.getSession().getAttribute(Constants.SESSIONID);
        SysUser user = sysUserService.selectByKey(userId);
        Map<String, Object> map = new HashMap<>(4);
        if (StringUtils.isNotBlank(title)) {
            map.put("title", StringUtils.isNotBlank(title) ? "%" + title + "%" : title);
        }
        map.put("type", user.getType() ? 1 : 0);
        if (isRead != null) {
            map.put("isRead", isRead);
        }
        map.put("userId", userId);
        return innerMailMapper.findAllNoticeByUserId(map);
    }

    @Override
    @SystemServiceLog(description = "findCountByUserId站内信记录")
    public int findCountByUserId(Long userId, int type) {
        Map<String, Object> map = new HashMap<>(3);
        map.put("type", type);
        map.put("isRead", false);
        map.put("userId", userId);
        return innerMailMapper.findAllNoticeCount(map);
    }

    @Override
    public List<InnerMail> findAll(InnerMailForm innerMailForm) {
        return innerMailMapper.findAll(innerMailForm);
    }

}
